JQuery Accordion и загрузка контента через AJAX - PullRequest
25 голосов
/ 14 марта 2009

Я хотел бы загрузить содержимое под каждым заголовком 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) анимация скольжения вниз не происходят.

Я думаю, что мне нужно было бы предотвратить анимацию скольжения вниз до тех пор, пока содержимое не загрузится (используя функцию обратного вызова load), но я не уверен, как подключить это к плагину accordion.

Любые идеи с благодарностью!

Ответы [ 14 ]

14 голосов
/ 22 марта 2013

Просто быстрым ходом.

Ни один из этих ответов не будет работать должным образом с последним API, так как после jQuery UI 1.9 события change и changestart были изменены на ' активации ' и ' перед активацией 'соответственно.

Надеюсь, что кто-то спасет несколько минут.

10 голосов
/ 01 декабря 2009

Это должно решить вашу проблему:

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

Хитрость в том, что аккордеон меняет классы живого контейнера, поэтому вы можете использовать .find (), чтобы найти активный аккордеон и выполнить над ним действие.

7 голосов
/ 05 июня 2009

Я столкнулся с той же проблемой, пытаясь загрузить аккордеон на вкладки ajax с помощью Jquery UI. Аккордеон не может быть инициализирован до того, как вы его уничтожите.

Вот пример кода JavaScript:

    $("#navigation").tabs({ 
    show: function(ui) {
        $('#browse').accordion('destroy').accordion({autoHeight: false, collapsible: true , active: false, header: 'h3'});
    } 
});
6 голосов
/ 17 марта 2009

Я только что сделал нечто подобное и обнаружил, что хитрость заключается в том, чтобы загрузить контент из ajax-запроса, как только DOM будет готов, и включить его в функцию обратного вызова запроса.

Я пытался сделать это с помощью функции загрузки 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();
        }
    });
}});

это должно сделать это ...

5 голосов
/ 16 мая 2011

Вот самый простой и легкий способ сделать это

    $("#accordion").accordion({
                active:false,
                change:function(event, ui) {
                    if(ui.newContent.html()==""){
                        ui.newContent.load(ui.newHeader.find('a').attr('href'));
                        }
                },
                autoHeight: false
            });
5 голосов
/ 18 января 2011

Я делал это раньше, позвольте мне скопировать и вставить это сюда.

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

});
4 голосов
/ 15 декабря 2011

Это должно решить проблему загрузки аккордеона до его активации:

<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>
2 голосов
/ 29 июля 2011

Это на самом деле намного проще, чем вы все разбираете!

В вашей функции готовности документа:

$('#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>
2 голосов
/ 25 февраля 2011

Возможно, это не совсем то же самое, о чем здесь говорится, но многие из этих фрагментов помогли мне получить свое решение, поэтому я подумал, что я могу поделиться им, если кому-то еще нужно сделать (точно!) То, что мне нужно было сделать .

Я хотел загрузить внешние фрагменты контента в аккордеон, но заставить его правильно изменить размер и т. Д. Было непросто, вот мое решение:

$(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 с тем же идентификатором, что и на каждой панели аккордеона, поэтому он знает, что и куда поместить!

2 голосов
/ 14 марта 2009

Подумав ненадолго, есть ли причина, по которой вы используете ajax для загрузки контента? По крайней мере, из вашего примера это выглядит так, как если бы контент мог быть загружен изначально и покончить с этим.

Что касается вашего вопроса, вы пробовали что-то вроде этого:

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

или изучили какой-либо другой способ, которым ваша загрузка может мешать взгляду аккордеона на дерево DOM? (например, попытаться загрузить более глубоко вложенный div)?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...