JQuery Accordion не «аккордеонизирует» новые панели, загружаемые через AJAX

Мне нужно загрузить панели аккордеона на одну из моих страниц с помощью AJAX, и я обнаружил, что JQuery «аккордеонизирует» все панели, определенные в файле HTML, но ни одна из панелей не загружается через Javascript. Еще одна маленькая причуда: я делаю это на вложенном аккордеоне — аккордеоне внутри аккордеона. Это начало аккордеона, если хотите.

Я проверил другие вопросы о переполнении стека и форум JQuery и обнаружил, что большинство из них касаются изменения размеров панелей после загрузки данных. Ближайший вопрос, который я нашел, был здесь, но он не отвечает мой вопрос, потому что попытка уничтожить, а затем повторно настроить мои панели, загруженные JS, не работает.

Это соответствующий раздел моего раздела заголовка html:

<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/themes/flick/jquery-ui.css" type="text/css" />  
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>  
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/jquery-ui.min.js"></script>  

<script type="text/javascript">  
  $(document).ready(function() {
    $(".accordion").accordion({
        collapsible: true, 
        icons: false,
        autoHeight: false,
        active: false 
    });
  });  
</script>

Это соответствующий раздел моего раздела html body:

<div class="accordion">
    <h3 id="acc1">First panel title</h3>
    <div>First panel content</div>

    <h3 id="acc2">Second panel title</h3>
    <div class="accordion" id="ajaxresults-aliaslist">This is where the nested accordion goes</div>

    <h3 id="acc3">Third panel title</h3>
    <div>Thirdpanel content</div>
</div>

<script type="text/javascript">
$("#ajaxresults-aliaslist").load("/loadaliaslist/");
</script>

Когда javascript загружает "/loadaliaslist/", он получает сообщение следующего содержания:

<h3>1st panel within a panel title</h3>
<div>1st panel within a panel content</div>

<h3>2nd panel within a panel title</h3>
<div>2nd panel within a panel content</div>

<h3>3rd panel within a panel title</h3>
<div>3rd panel within a panel content</div>

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

Верно, еще кое-что: я попробовал две вещи, которые не сработали:
- Я попытался поместить и скрипт загрузки, и скрипт аккордеона внизу страницы (сначала загрузить), надеясь, что порядок будет иметь значение. (нубиш? не уверен...)
- Я попытался добавить скрипт в конце, чтобы уничтожить и воссоздать панели следующим образом:

$("#ajaxresults-aliaslist").accordion('destroy').accordion();

Это все. Я действительно надеюсь, что кто-то из аккордеонов Леонардо ДиКаприо сможет помочь мне выйти из затруднительного положения. Очень признателен!


person jchung    schedule 20.05.2011    source источник


Ответы (3)


Не проверено, но попробуйте что-то вроде этого...

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

$(function() {
    var config = {
        collapsible: true, 
        icons: false,
        autoHeight: false,
        active: false
    }
    $(".accordion").live('load', function(){
        $(this).accordion(config);
    }).accordion(config);
});

РЕДАКТИРОВАТЬ: немного изменил код (еще не проверенный).

person wdm    schedule 20.05.2011
comment
Я пробовал, но эффекта вроде нет. Просто проверяю: я заменил свой оригинальный $(document).ready(function) на этот и поместил его в конец страницы. Это было бы, если бы вы выполнили этот скрипт? - person jchung; 20.05.2011
comment
Попробуйте поместить это в функцию $(document).ready. Я не включил его, потому что подумал, что это будет лишним. - person wdm; 20.05.2011
comment
Нет игральных костей. Есть ли способ подтвердить вашу гипотезу об обработчиках событий? - person jchung; 20.05.2011
comment
Ознакомьтесь с документацией live(): метод .live() может воздействовать на элементы, которые еще не были добавлены в DOM, с помощью делегирования событий api.jquery.com/live - person wdm; 21.05.2011
comment
Я просмотрел документы live() и попытался решить проблему с помощью live, но не смог правильно связать ее. Однако я нашел решение своей проблемы. Смотрите редактирование для решения. Еще раз спасибо @wdm - person jchung; 21.05.2011

РЕДАКТИРОВАТЬ ИЗ ОП: НАЙДЕНО РЕШЕНИЕ

Поиграв больше, я нашел способ решить эту проблему, пока AJAX загружает новые данные сразу при загрузке страницы. Решение состояло в том, чтобы вызвать функцию аккордеона только один раз, сразу после загрузки. Как в решении ниже:

<script type="text/javascript">  
$("#ajaxresults-aliaslist").load("/loadaliaslist/",  
    function(response, status, xhr) {    
    if (status == "error") {   
        var msg = "Sorry but there was an <strong>error</strong>: ";   
        $("#error").html(msg + xhr.status + " " + xhr.statusText);   
    }  
/* All panels are accordionized immediately after loading the content */   
    $(".accordion").accordion({   
        collapsible: true,  
        icons: false,  
        autoHeight: false,  
        active: false  
     });   
});   
</script>  

Предостережение: это будет работать, только если все содержимое аккордеона загружается немедленно. Если есть фрагменты контента, загруженные после первого аккорда

person jchung    schedule 20.05.2011

Я полагаю, что вы хотите сбросить управление аккордеоном. Попробуйте сделать это:

$('#accordion')[0].innerHTML = "";

После этого заполните элемент управления HTML-кодом с помощью оператора append.

person oscar    schedule 30.08.2011