jQuery Accordion并通过AJAX加载内容

时间:2009-03-14 18:20:15

标签: jquery-ui jquery

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

$(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(相关代码段

<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)上中断手风琴插件的下滑动画,下滑动画不会发生。

我认为我需要阻止下载动画直到内容加载(使用加载回调函数),但我不确定如何将其挂钩到手风琴插件中。

任何想法都非常感谢!

14 个答案:

答案 0 :(得分:14)

快速抬头。

自从jQuery UI 1.9以来,这些答案都不会像预期的那样有效,因为事件changechangestart已被更改为“activate”和“{{3}分别为。

希望能节省几分钟。

答案 1 :(得分:10)

这可以解决您的问题:

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

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

答案 2 :(得分:7)

我在尝试使用Jquery UI将accordion加载到ajax标签时遇到了同样的问题。 手风琴在摧毁之前不能初始化。

以下是示例javascript代码:

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

答案 3 :(得分:6)

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

我尝试使用jquery的加载函数,但遇到了麻烦,最后使用了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 :(得分:5)

我已经完成了这个,然后让我复制并粘贴到这里。

<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'));
            }

});

答案 5 :(得分:5)

这是最简单,最简单的方法

    $("#accordion").accordion({
                active:false,
                change:function(event, ui) {
                    if(ui.newContent.html()==""){
                        ui.newContent.load(ui.newHeader.find('a').attr('href'));
                        }
                },
                autoHeight: false
            });

答案 6 :(得分:4)

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

<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>

答案 7 :(得分:2)

只是在盒子外思考片刻,你有没有理由使用ajax来加载内容?从你的例子来看,它看起来好像最初只能加载内容并完成它。

至于你的实际问题,你有没有试过这样的事情:

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

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

答案 8 :(得分:2)

也许这与在这里讨论的内容完全相同,但很多这些片段帮助我让我的解决方案正常工作,所以我认为id分享它,任何人都需要做(确切地说!)我需要做什么

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

$(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文件中有一个div与每个手风琴面板具有相同的id,所以它知道放在哪里!

答案 9 :(得分:2)

这实际上比你们所有人都要容易得多!

在你的doc ready函数中:

$('#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>

答案 10 :(得分:1)

我一直在处理这个问题,使用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);


         }

     });

答案 11 :(得分:1)

我相信这是尚未给出的最简单的答案,并且满足所有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);
        });

    }
});

答案 12 :(得分:0)

$( "#accordion" ).bind( "accordionchange", function(event, ui) {   
    if (ui.newHeader.text()=="LaLaLa"){
       do here ....
    }
   });

答案 13 :(得分:0)

我正在寻找同一个问题的答案,并在这里尝试了几个例子。但是,我使用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);
         }
});