jQuery mobile agrega animación al conjunto plegable

I would like to add an animation to collapsible set with jQuery móvil. Let me show a simple example of this:

<div id="tiles" data-role="collapsible-set" data-iconpos="right">
   <div class="tile" data-role="collapsible" data-iconpos="right">blablabla</div>
   <div class="tile" data-role="collapsible" data-iconpos="right">blablabla</div>
   <div class="tile" data-role="collapsible" data-iconpos="right">blablabla</div>
</div>

jQuery móvil handles this perfectly and shows me collapsible set of 3 items. What I want is ANIMATION, however I seem not to find anything in the docs.

I haven't tested yet how simple Animación CSS(animating height property) would work, however is there a jQuery móvil way of doing it like turning some internal flag ?

EDITAR I have tested out a simple jQuery animate method and it actually works. Just in case anyone else needs this. It runs smoothly even on my 528MHz Android phone on a default browser. A snippet I have added is really simple:

$( ".ui-collapsible-heading" ).live( "click", function(event, ui) {
    $(this).next().css('height', '0').animate({
        height: '100px'
    });
});

preguntado el 03 de mayo de 12 a las 21:05

Not out of the box. I think the problem is handling page/viewport dimensions (aka height) during an "expand" or "collapse" transition. Right now you click on a collapsible and when the collapsible is open, the relevant heights get updated. Doing this "in transition" probably looks awful besides being a resouce strainer. Still you could try by just adding/removing the respective transition-classes (slide-up/down in out - check JQM CSS) to the expand and collapse event inside the JQM collapsible widget. Then see what happens :-) -

@frequent jQuery Mobile exposes the expand y collapse events for collapsible widgets. If you bind to these events you can stop the default behavior and animate the event instead. See my answer below. -

@Jasper I knew about the events, didn't know they are exposed. Thx! I'm also using the JQM css3 classes for non-page elements. The difficult part with collapsibles is them being "inline/static" elements (vs. positioned absoltely). So when I use css3 animations on inline elements I have no way to update things like page-padding during the transition. So on ios4 for example with polyfill fixed footer, the footer will be pushed out of view during the transition - not that thats a serious problem, but still... -

@frequent I haven't tried it but you could try to absolutely position the collapsible content. Leave the header alone so it takes the necessary space, then make the content absolutely positioned so it won't take space-up when it expands. You may need to set the collapsible container element's position to relative so it's children use it as their offset parent. -

@Jasper - I tried position:absolute, when playing around with the collapsible-set (changed it into a tabviewer = left to right). While it's easier to set the tab width dimensions like this, it was terrible if individual tabs had different height, because there just was no way to make this work with pos:abs/rel. I can dig out an example if you want to have a look. -

4 Respuestas

Aqui tienes:

$('[data-role="collapsible"]').bind('expand collapse', function (event) {
    $(this).find('p').slideToggle(500);
    return false;
});​

I liked the idea you were going for so I played around with it a bit. This hooks into the way jQuery Mobile controls collapsible widgets so it's a bit less hacky then binding to the heading element.

La return false; stops the default behavior and the other line toggles the content in/out of view using the jQuery slideUp/slideDown animations. You could also use .fadeToggle() or roll your own animations. If you check event.type you can animate based on the event fired.

Aquí hay una demostración: http://jsfiddle.net/VtVFB/

contestado el 04 de mayo de 12 a las 00:05

I don't have a lot of experience with html, but I'm messing around with jquery mobile right now. Where exactly would this code snippet go? - Ryan

@Ryan I would place this code inside a pageinit event handler for a specific page or set of pages: $(document).on("pageinit", "#somePageID, #someOtherPageID", function () { ... PLACE CODE HERE ... });. Esto pageinit event handler should be run in the global scope. - Jaspe

I've been trying to get this to work, but I keep getting a syntax error on }); My code is: $(document).on("pageinit", "[data-role='page']", function () { $("[data-role='collapsible']").bind("expand collapse", function (event) { });​ }); - BuceoSteve

@ScubaSteve I don't see any syntax errors in the code you posted. Also, I'd prefix your inner select to use $(this).find(... so that you only bind to the collapsible elements for the page that is being initialized. - Jaspe

Please note that in jQuery Mobile 1.4 and up you need to bind to the collapsibleexpand y collapsiblecollapse eventos en lugar de expand y collapse. So the complete code becomes

$('[data-role="collapsible"]').on('collapsibleexpand collapsiblecollapse', function(event) {
    $(this).find('p').slideToggle(500);
    return false;
});

Respondido 29 ago 14, 09:08

This worked for me, can you explain how does this selector work? $('[data-role="collapsible"]') - minghuang

​The code is not entirely right. It overrides the default jquery mobile implementation of the expand collapse events, but does not handle the change of the expand collapse icons.

A better code will be:

$('[data-role="collapsible"] h3:first').bind('click', function (event) {
   $(this).next('p').slideToggle(500);
   return false;
});​

contestado el 28 de mayo de 13 a las 06:05

The accepted answer doesnt account for that it doesnt change the collapsible cursor because of return false, so this is my answer working:

In my Project it was the contents relative to the [date-role="collapsible"] se encuentran las $(this).find('>*:not(h3)')

/* animate collapsible-set */
$('[data-role="collapsible"]').on('expand', function (event) {
    $(this).find('>*:not(h3)').each(function() {
        if (!$(this).is(':visible')) {
            $(this).stop().slideToggle();
        }
    });
}).on('collapse', function (event) {
    $(this).find('>*:not(h3)').each(function() {
        if ($(this).is(':visible')) {
            $(this).stop().slideToggle();
        }
    });
});

Respondido 25 ago 15, 22:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.