【问题标题】:jQuery Accordion and loading content through AJAXjQuery Accordion 和通过 AJAX 加载内容
【发布时间】:2009-03-14 18:20:15
【问题描述】:

我想使用 jQuery load 命令加载每个 jQuery accordion 标头下的内容。目前,我已将其设置为以下

$(function() {

    $("#accordion").accordion({          
        header: "h2",
        active: false              
    });

    $("h2", "#accordion").click(function(e) {
        var contentDiv = $(this).next("div");
        contentDiv.load($(this).find("a").attr("href"));      
    });                    
});

和 HTML(相关的 sn-p

<div id="accordion">
    <div>
        <h2><a href="home.htm">Home</a></h2>
        <div>
           <!-- placeholder for content -->
        </div>
    </div>
    <div>
        <h2><a href="products.htm">Products</a></h2>
        <div>
           <!-- placeholder for content -->       
        </div>
    </div>
</div>

现在一切正常,但存在一个问题,以这种方式加载内容会中断手风琴插件在某些浏览器(IE6)和其他浏览器(FF)上的向下滑动动画,向下滑动动画不会发生。

我想我需要在内容加载(使用加载回调函数)之前阻止向下滑动动画的发生,但我不确定如何将其挂接到手风琴插件中。

任何想法都非常感谢!

【问题讨论】:

  • 你能发布你的最终解决方案吗?
  • @HonorGod 我很久以前就发布了这个问题,我不再记得我最终采用了什么解决方案。我会看看我是否可以重新审视这个并得到一个明确的答案

标签: jquery-ui jquery


【解决方案1】:

请注意。

这些答案都不会像预期的那样使用最新的 API,因为自 jQuery UI 1.9 以来,事件 changechangestart 已分别更改为 'activate' 和 'beforeActivate'。

希望能节省几分钟。

【讨论】:

    【解决方案2】:

    这应该可以解决您的问题:

        $('#accordion').accordion({ 
        changestart: function(event, ui){
            var clicked = $(this).find('.ui-state-active').attr('id');
            $('#'+clicked).load('/widgets/'+clicked);
        }
    });
    

    它的诀窍是手风琴改变了活动容器的类,因此您可以使用 .find() 来定位活动的手风琴并对其执行操作。

    【讨论】:

    • 实际上,这个特定的代码有一个错误,它不能正常工作。如果要查找“.ui.state-active”元素,则需要将事件从“changestart”更改为“change”。否则,您将在 jQueryUI 将类应用于标题元素之前调用该函数。结果:change: function(event, ui) { ... }
    • 我无法 +1 Danny 的评论,如果您打开一个 FF 调试窗口并观察当您以 mogmismo 的方式执行此操作时会发生什么,您会注意到当您“折叠”时您会获得点击的 ID手风琴......不是当你展开它......将事件更改为“更改”解决了问题
    • 注意 - 对于当前版本的 jqueryui,事件现在是 beforeActivate。另外,您可以通过ui.newHeader 获取即将打开的标题
    • 我的建议:检查API here版本,因为事件发生了变化
    【解决方案3】:

    我刚刚做了类似的事情,发现诀窍是在 DOM 准备好后立即从 ajax 请求中加载内容,并在请求的回调函数中启用手风琴。

    我尝试使用 jquery 的 load 函数来做,但遇到了麻烦,最终改用了 ajax 函数。

    在您有多个 ajax 调用的情况下,我想您可以将每个调用嵌套在前一个的回调函数中。这确实是一种非常低效的方法,但如果它们只是小文本文件,应该没问题。

    示例如下:

    $.ajax({type:"get",url:"home.htm",success: function(data){
        $("#homeDiv").html(data);
        $.ajax({type:"get",url:"products.htm",success: function(data){
                $("#productsDiv").html(data);
                $("#accordion").accordion();
            }
        });
    }});
    

    应该这样做......

    【讨论】:

      【解决方案4】:

      我在尝试使用 Jquery UI 将手风琴加载到 ajax 选项卡时遇到了同样的问题。 在销毁之前无法初始化手风琴。

      这里是示例 javascript 代码:

          $("#navigation").tabs({ 
          show: function(ui) {
              $('#browse').accordion('destroy').accordion({autoHeight: false, collapsible: true , active: false, header: 'h3'});
          } 
      });
      

      【讨论】:

      • 我在其末尾添加了一个 .accordion('activate', last_index) 以在手风琴可折叠时弹出最后打开的部分。
      【解决方案5】:

      这是最简单的方法

      $("#accordion").accordion({ 主动:假, 更改:函数(事件,用户界面){ if(ui.newContent.html()==""){ ui.newContent.load(ui.newHeader.find('a').attr('href')); } }, 自动高度:假 });

      【讨论】:

        【解决方案6】:

        在此之前我已经完成了,让我将其复制并粘贴到此处。

        <div class="accordion">
            {section name=cat_loop loop=$cats}
                    <h3  data-id="{$cats[cat_loop].subcat_id}">
                        <a href='#' rel='loaderAnchor' id='lanch-{$cats[cat_loop].subcat_id}'>
                            {print id=$cats[cat_loop].subcat_title}
                        </a>
                    </h3>
                    <div id='section-{$cats[cat_loop].subcat_id}' >
                        {include file='include/section_profile_fields.stpl'}
                    </div>
            {section}
        <div>
        

        {} 中的内容包含服务器端脚本,基本上是一个循环,用于为多个手风琴打印内容。这是javascript:

        jQuery('.accordion').accordion({
                    changestart: function(event, ui){
                           var $activeCord = jQuery(this).find('.ui-state-active');
                           var contentDiv = $activeCord.next("div");
                        contentDiv.load('ajax_member_profile_edit.aspx?cat_id='+$activeCord.attr('data-id'));
                    }
        
        });
        

        【讨论】:

          【解决方案7】:

          这应该可以解决在激活之前加载手风琴的问题:

          <script type="text/javascript">//<![CDATA[
          $(document).ready(function() {
          
            $("#accordion").children("div").each( function() {
              var a = $(this).find("a");
              var ref = $(a).attr("href");
              $(a).attr("href", "#");
              $(this).find("div").load(ref);
            });
          
            $("#accordion").ajaxStop(function() {
              $(this).accordion({
                header: "h2",
                active: false,
                collapsible: true,
                clearStyle: true
              });
            });
          
          })
          //]]></script>
          <div id="accordion">
            <div><h2><a href="home.htm">Home</a></h2><div></div></div>
            <div><h2><a href="products.htm">Products</a></h2><div></div></div>
          </div>
          

          【讨论】:

            【解决方案8】:

            只是跳出框框思考一下,您使用 ajax 加载内容有什么原因吗?至少从您的示例中看起来,好像内容可以最初加载并完成。

            至于您的实际问题,您是否尝试过这样的事情:

            var contentDiv = $(this).find("div");
            

            或探索任何其他方式,您的加载可能会干扰手风琴的 DOM 树视图? (例如,尝试加载嵌套更深的 div)?

            【讨论】:

            • 我正在考虑将每个手风琴窗格的内容与实际的“菜单”页面分离/解耦,并且仅在必要时加载它。窗格最终将在运行时从数据源动态生成...
            • 在文档准备好后加载每个窗格的内容不会有任何问题,除了性能之外(我目前不知道将来可能有多少个窗格)。
            • 是的,但是看起来您仍然可以在生成页面时在服务器端执行该操作,而不是在每次更改选项卡时强制执行一系列往返。大多数 Web 框架都支持这种解耦,而无需大惊小怪。
            • 你在这里让我深思熟虑,我可能会在稍后阶段最终这样做。但是,我还是想解决原来的问题!
            • 因此,第一步,尝试将更新后的元素隐藏在结构中的更深处。报告它的作用并...
            【解决方案9】:

            也许这与这里讨论的内容不完全一样,但其中很多 sn-ps 帮助我让我的解决方案正常工作,所以我认为 id 分享它以防其他人需要做(完全正确!)我需要的去做。

            我想将外部内容片段加载到手风琴中,但让它正确调整大小等很麻烦,这是我的解决方案:

            $(document).ready(function () { //All the content is loaded at page load which means you dont get screwy animations
                $('#accordion').accordion({
                    autoHeight: false, // set to false incase theres loads more in one panel than the others
                    create: function (event, ui) {
                        $('div#accordion > div').each(function () { //for each accordion panel get the associated content from external file and load it in.
                            var id = $(this).attr('id');
                            $(this).load('ajax_content.html #' + id, function () {
                                $('#accordion').accordion('resize');
                            });
                        });
                    }
                });
            });
            

            希望这对某人有帮助 =)

            哦,我应该提到,显然在 ajax_content.html 文件中有一个与每个手风琴面板具有相同 id 的 div,因此它知道将什么放在哪里!

            【讨论】:

              【解决方案10】:

              这实际上比你们想象的要容易得多!

              在您的文档就绪函数中:

              $('#accordion').accordion();
              $("#accordion").click(function(e) {
                $('.ui-accordion-content-active').load('/path/to/content');
              });
              

              和你的 html

              <div id = "accordion">
                <h3>Click me</h3>
                <p>Loading....</p>
                <h3>Or even click me!</h3>
                <p>Loading...</p>
                <h3>Etc..</h3>
                <p>Loading</p>
              </div>
              

              【讨论】:

                【解决方案11】:

                我一直在使用 jquery 1.4 处理这个问题,这就是我解决它的方法。 “ui”对象有两个重要的属性“newContent”和“newHeader”。我使用 newContent 并在将保存内容的 div 上放置了一个 id。我还有一个隐藏的输入标签来保存重要数据,感觉更干净。

                 $("#accordion").accordion({
                         disabled: false,
                         autoHeight: false,
                         collapsible: true,
                         active: false,
                         header: 'h2',
                         animated: 'bounceslide',
                         changestart: function (event, ui) {
                             var location = ui.newContent.find('input:hidden[name=location]').val();
                             ui.newContent.find('#data').load(location);
                
                
                         }
                
                     });
                

                【讨论】:

                  【解决方案12】:

                  我相信这是尚未给出的最简单的答案,并且满足 OP 的所有要求...在显示 div 之前加载,并根据 a 标签的 href 动态加载:

                  $("#accordion").accordion({
                  
                      active: false,
                      clearStyle: true,
                      changestart: function(event, ui){
                  
                          var href = $(ui.newHeader.find("a")).attr("href");
                  
                          $.post(href, function(data) {
                  
                              ui.newHeader.next("div").html(data);
                          });
                  
                      }
                  });
                  

                  【讨论】:

                    【解决方案13】:

                    我一直在寻找相同问题的答案,并在此处尝试了几个示例。但是,使用带有 ui-state-active 的示例,我得到了一个未定义的值:

                    var clicked = $(this).find('.ui-state-active').attr('id');
                    

                    我还想确保仅在每个手风琴面板第一次展开时才调用 .load 函数。通过结合其他几个海报的答案,我得到了我想要的结果:

                    $('#accordion').accordion({ 
                        changestart: function(event, ui){
                             if(ui.newContent.html() == ""){
                                 var id = ui.newContent.attr("id");
                                 ui.newContent.load("[your url]" + id);
                             }
                    });
                    

                    【讨论】:

                      【解决方案14】:
                      $( "#accordion" ).bind( "accordionchange", function(event, ui) {   
                          if (ui.newHeader.text()=="LaLaLa"){
                             do here ....
                          }
                         });
                      

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2012-11-26
                        • 1970-01-01
                        • 2011-01-21
                        • 1970-01-01
                        • 2011-10-26
                        • 2013-11-24
                        相关资源
                        最近更新 更多