Подтвердить что ты не робот

JQuery Аккордеон и загрузка содержимого через AJAX

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

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

Любые идеи очень ценятся!

4b9b3361

Ответ 1

Просто быстро справляйтесь.

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

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

Ответ 2

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

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

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

Ответ 3

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

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

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

Ответ 4

Я только что сделал что-то подобное, и нашел, что трюк состоял в том, чтобы загрузить контент из запроса 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

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

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

});

Ответ 6

Вот простейший и простой способ сделать это

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

Ответ 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

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

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

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

Ответ 9

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

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

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

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

Ответ 10

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

Мне захотелось загрузить внешние фрагменты контента в аккордеон, но правильно его изменить и т.д. было fiddley, heres мое решение:

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

Ответ 11

Я имел дело с этой проблемой, используя jquery 1.4, и вот как я ее решил. Объект "ui" имеет две важные пропозиции: "newContent" и "newHeader". Я использовал newContent и поместил id в div, который будет содержать контент. Я также скрытый тег ввода для хранения важных данных, он просто чувствовал себя чище.

 $("#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 показан и динамически соответствует href тега a:

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

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

Ответ 14

Я искал ответ на тот же вопрос и попробовал пару примеров здесь. Тем не менее, я получил значение undefined, используя пример с активностью ui-state:

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