Сворачиваемый виджет JQuery Mobile сворачивает и разворачивает события, которые не работают

У меня есть страница динамически созданных складных элементов JQuery 1.3.1 (не в наборе аккордеона), и я пытаюсь сохранить развернутое или свернутое состояние каждого элемента. Складные элементы прекрасно работают без каких-либо обработчиков. Мой код для подключения обработчиков находится здесь, который я вызываю в pagebeforeshow (я пробовал и в pageshow):

function bindCollapsibleHistoryHandlers(){
    function getHandler(field, value){
        var handler = function(event, ui){
            var element = event.target.id;
            var id = (element.split('-'))[1];
            var status = window.mam_history.status('meetings', id);
            if (null == status){
                status = { "open": false, "note_open": false, "dist_open": false };
            }
            status[field] = value;
            var new_status = null;
            window.mam_history.status('meetings', id, status);
                        return true;
        }
        return handler;
    }

    $('.mtg_item').off('collapsiblecollapse');
    $('.mtg_item').on('collapsible', getHandler('open', false));
    $('.mtg_item').off('collapsibleexpand');
    $('.mtg_item').on('collapsibleexpand', getHandler('open', true));

    $('.dist_info').off('collapsiblecollapse');
    $('.dist_info').on('collapsiblecollapse', getHandler('dist_open', false));
    $('.dist_info').off('collapsibleexpand');
    $('.dist_info').on('collapsibleexpand', getHandler('dist_open', true));
}

Один из HTML-элементов выглядит в инспекторе Chrome так:

введите здесь описание изображения

Согласно документации JQuery Mobile 1.3.1, перехватываются следующие события: collapsiblecollapse и collapsibleexpand. Когда я пытаюсь использовать их, обработчики событий никогда не вызываются. Глядя в Интернете, я заменил эти события на collapse и expand. При этом обработчик событий будет вызываться при нажатии на сворачиваемый виджет, но сворачиваемый виджет не будет сворачиваться или расширяться ни до, ни после запуска обработчика. Это не только визуальная проблема, потому что состояние разборки, прочитанное с помощью .collapsible('option', 'collapsed'), также не изменилось.

Внутри обработчика я пробовал различные комбинации добавления или удаления класса ui-collapsible-collapsed или установки опции collapsible перед .trigger('create') и даже активации collapsiblecollapse и collapsibleexpand внутри обработчика (конечно, когда он был привязан к collapse и expand). Удаление строк .off() ничего не изменило (не представляю, почему). Ничто из того, что я пробовал до сих пор, не приведет к сворачиванию или расширению складного объекта при нажатии, когда обработчик фактически запускается, будучи привязанным к collapse или expand. Неважно, какой код на самом деле находится в обработчике или есть ли у меня атрибут data-collapsed в теге <div> для начала или нет.

Так что, похоже, мне что-то не хватает, и я был бы признателен за любую помощь, чтобы увидеть ошибку на моем пути.


person chrysanhy    schedule 17.06.2013    source источник
comment
Можете ли вы настроить jsfiddle, хотите проверить html-коды после добавления?   -  person yeyene    schedule 17.06.2013


Ответы (1)


Решение

Рабочий пример: http://jsfiddle.net/Gajotres/3pCQh/

Как вы заметили, правильный способ обнаружения сворачиваемого состояния - использовать событие сворачивания и расширения (информация, представленная в официальной документации, неверна). Также при связывании событий в jQuery Mobile, особенно с динамически создаваемыми объектами, важно использовать делегированное связывание, например:

$(document).on( "collapse", "#test-collapsible", function( event, ui ){
    alert('Close');
});

$(document).on( "expand", "#test-collapsible", function( event, ui ){
    alert('Open');
});  

В этом примере все равно, существует объект или нет. Событие будет привязано к объекту документа и будет передано правильному адресату, только если/когда объект станет доступным внутри DOM.

Несколько заметок

Если вы используете правильное событие страницы (например, pageinit), вам не нужно использовать off для отмены привязки события. Pageinit срабатывает только один раз, как и документ готов при использовании классического jQuery.

Есть еще одна вещь. Если вы используете несколько страниц HTML, вам нужно быть осторожным с вашим javascript. Когда jQuery Mobile загружает дополнительные страницы HTML, он загружает только контент BODY, поэтому все содержимое HEAD будет отброшено. Это также может быть причиной того, что ваш пример кода не выполняется. Решения этой проблемы можно найти ЗДЕСЬ.

person Gajotres    schedule 17.06.2013
comment
Сработало изменение on() на делегированную привязку. Большое спасибо! - person chrysanhy; 17.06.2013