2

Я хочу, чтобы интегрировать разборный в моем jQM приложении (1.3.2), которая работает следующим образом:Как я могу отложить расширение складного до тех пор, пока его содержимое не будет получено?

  1. Он начинает разрушился.
  2. При щелчке он начинает извлекать списки для сбрасываемых с сервера. складной остается закрытым, значок загрузки может вращаться.
  3. После того, как все элементы загружены, а список обновлен и готов, сборщик разворачивает расширения.
  4. Если нажать ее снова, она закрывается непосредственно без задержки, и начинается с 1.

Моя первоначальная идея была, чтобы захватить expand событие и предотвратить его распространение. Когда загрузка завершена, я де-зарегистрирую свой обработчик пользовательских событий, чтобы вернуть сбрасываемый обратно в нормальное состояние и, наконец, запустить событие расширения из JavaScript для открытия.

Проблема в том, что это работает для первого раунда, но впоследствии складной открывается в любом случае. Рассмотрим следующий пример (также в jsfiddle):

<div data-role="collapsible" id="c"> 
    <h2>Collapse</h2> 
    <ul data-role="listview" id="lv"> 
    <li>You don't see me!</li> 
    </ul> 
</div> 

<a href="#" data-role="button" onClick="$('#c').off('expand', stop)"> 
    Unlock the collapsible 
</a> 

<a href="#" data-role="button" onClick="$('#c').on('expand', stop)"> 
    Lock the collapsible 
</a> 

JavaScript:

var stop = function(event) { 
    alert('Locked!'); 
    event.preventDefault(); 
} 

// executed after the element is created ... 
$('#c').on('expand', stop) 

Здесь, если вы нажмете на разборную после загрузки, она остается закрытой (хорошо). Когда вы нажимаете кнопку разблокировки, она открывается и предупреждение не отображается (хорошо). Если вы снова заблокируете его, оно отобразит предупреждение (хорошее), но все равно откроется (плохо).

Может ли кто-нибудь просветить меня, что я делаю неправильно? Кажется, есть побочные эффекты от разблокировки, которые я не вижу. Здесь есть несколько подобных вопросов, но большинство из них довольны тем, что просто предотвращают расширение, не возвращая его снова.

Так что мой вопрос: Каков наилучший способ отсрочить расширение складного навеса?


Edit: Я добавил еще один пример, который объединяет логику ListView, а также показывает эту ошибку. jsFiddle is here. Я также переехал в .one(), чтобы сделать деинсталляцию более прослеживаемой.

Новый JavaScript:

var stop_n_load = function (event) { 
    alert('stop opening! (or at least try to ...)'); 

    // try to stop the expanding by stopping the event 
    event.preventDefault(); 

    // Do some work that takes time and trigger expand afterwards ... 
    setTimeout(function (e) { 
    dd = new Date(); 
    $('#lv').empty(); 
    $('#lv').append("<li><a href='#'>Item A ("+dd+")</a></li>"); 
    $('#lv').append("<li><a href='#'>Item B ("+dd+")</a></li>"); 
    $('#lv').listview('refresh'); 

    // when done, start expanding without this handler (was register only once) 
    $('#c').trigger('expand'); 
    // for the next collapse register stop_n_load again 
    $('#c').one('collapse', reset); 
    }, 2000); 
}; 

var reset = function (event) { 
    $('#c').one('expand', stop_n_load); 
}; 

$('#c').one('expand', stop_n_load); 

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

Там, кажется, проблема с .preventDefault() я не понимаю ...

+0

вам нужно использовать 'вернуть false' =' preventDefault() 'и' stopPropagation() 'вместе. проверьте это http://jsfiddle.net/Palestinian/yXa4W/ – Omar

+0

Спасибо @Omar, это выглядит великолепно! Почему в событии клика нет проблемы с тем, что '.preventDefault()' все еще установлен во втором клике? И можете ли вы ответить на ваш комментарий? –

+0

, когда разворачивается расширяемый, класс 'ui-collapsible-collapsed' удаляется, поэтому второй щелчок работает нормально. – Omar

ответ

2

Когда запускаются события expand/collapse, jQM добавляет несколько классов, чтобы показать/скрыть содержимое, а также обновить сворачиваемую кнопку/заголовок.

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

Когда разборный срублен, он имеет класс ui-collapsible-collapsed и после его расширения класс удаляется. Поэтому, когда запускается collapse, он работает нормально без перерывов.

$(".ui-collapsible-heading-toggle").on("click", function (e) { 

    // check if collapsible is whether expanded or collapsed 
    if ($(this).closest(".ui-collapsible").hasClass("ui-collapsible-collapsed")) { 

     // true 
     // stop "expand" event on click,tap,vclick,touchstart, etc... 
     e.stopImmediatePropagation(); 

     // show loading msg - optional 
     $.mobile.loading("show", { 
      text: "Loading...Please wait", 
      textVisible: true 
     }); 

     // for demo 
     // add items, expand and hide loading msg 
     setTimeout(function() {     
      $("#lv").empty().append(items).listview("refresh"); 
      $("#c").trigger("expand"); 
      $.mobile.loading("hide"); 
     }, 1000); 
    } 

    // false 
    // collapse normally or do something else 
}); 

Demo

1

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

var stop = function(event) {  
    $(this).find('.ui-listview').empty() 
    event.preventDefault(); 

    /* do ajax and then refresh component with expand enabled */ 
} 

$('#c').on('expand', stop); 

DEMO - without ajax

+0

Спасибо за ваш ответ, это только частично решает мою проблему, потому что вы все еще можете видеть сворачивающееся реагирование (добавляется некоторое пустое место под ним, значок меняется). [Я сделал еще одну скрипку с дополнительной логикой списка] (http://jsfiddle.net/mwil/nCjLX) с интегрированной идеей, вы должны увидеть проблему. Должно быть решение, чтобы получить события прямо, он работает так, как я хочу, на первом щелчке после всех ... –

+0

Я предполагаю, что браузер/устройство depeendednt .... я не так, как вы используете мои браузеры браузера FF и Chrome на окнах – charlietfl

0

После вброд вокруг в системе событий, я пришел к выводу, что на данный момент, если вы установите preventDefault() когда вы застряли с ним навсегда. На основе решения charlietfl Я добавил код, чтобы сделать визуальное воздействие минимальным, возможно, есть и способ предотвратить обновление GUI за 20 мс, чтобы сделать его полностью незаметным.

var stop_n_load = function (event) { 
    $('#lv').empty(); 
    $('#lv').listview('refresh'); 

    setTimeout(function() { 
    $('#c').trigger('collapse'); 
    }, 20); 

    // Do some work that takes time and trigger expand afterwards ... 
    setTimeout(function() { 
    dd = new Date(); 
    $('#lv').empty(); 
    $('#lv').append("<li><a href='#'>Item A (" + dd + ")</a></li>"); 
    $('#lv').append("<li><a href='#'>Item B (" + dd + ")</a></li>"); 
    $('#lv').listview('refresh'); 

    $('#c').trigger('expand'); 
    $('#c').one('collapse', reset); 
    }, 2000); 
}; 

Я все еще ищу решение, которое сбрасывает событие в прежнее состояние.

Смежные вопросы

 Смежные вопросы